package cn.calm.linksource.service.impl;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.log4j.Logger;

import cn.calm.commons.entity.BaseEntity;
import cn.calm.commons.entity.LogicallyDelete;
import cn.calm.commons.entity.PageMode;
import cn.calm.commons.exception.DeskException;
import cn.calm.commons.service.defaultimpl.DefaultQueryConditionBuilder;
import cn.calm.commons.service.defaultimpl.DefaultServiceImpl;
import cn.calm.commons.service.defaultimpl.EqualQueryConditionBuilder;
import cn.calm.entity.LinkSource;
import cn.calm.linksource.service.ILinkSourceService;

public class LinkSourceServiceImpl<T extends LinkSource> extends DefaultServiceImpl<T> implements
		ILinkSourceService<T> {
	static final Logger logger = Logger.getLogger(LinkSourceServiceImpl.class);
	
	public PageMode listPage(PageMode page, T t) {
		
		logger.debug("listPage start");
		if(t instanceof LogicallyDelete){
			((LogicallyDelete) t).setDeleteClass(LogicallyDelete.DELETECLASS_NORMAL);
		}
		try {
			return baseDao.listPage(page, t.getClass(),new DefaultQueryConditionBuilder<T>(t){
				@Override
				public void query(CriteriaBuilder b, CriteriaQuery<?> queryq,Root<? extends BaseEntity> root) {
					Class<? extends BaseEntity> clazz = t.getClass();
//					Root<? extends BaseEntity> root = queryq.from(clazz);

					Field[] fields = clazz.getDeclaredFields();
					List<Predicate> predicates = new ArrayList<Predicate>();
					buildWherePredicate(t, b, root, fields, predicates);
					Predicate[] predicateTemp = new Predicate[predicates.size()];
					predicates.toArray(predicateTemp);
					queryq.where(predicateTemp);
					queryq.orderBy(b.asc(root.get("sourceType")),b.asc(root.get("disOrder")));
				}
			});
		} finally {
			logger.debug("listPage end");
		}
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.commons.service.IBaseService#list(cn.desk.commons.entity.BaseEntity
	 * )
	 */
	@Override
	public List<T> list(T t) {
		logger.debug("list start");
		try {
			return baseDao.list(t.getClass(), new DefaultQueryConditionBuilder<T>(t){
				@Override
				public void query(CriteriaBuilder b, CriteriaQuery<?> queryq,Root<? extends BaseEntity> root) {
					Class<? extends BaseEntity> clazz = t.getClass();
//					Root<? extends BaseEntity> root = queryq.from(clazz);

					Field[] fields = clazz.getDeclaredFields();
					List<Predicate> predicates = new ArrayList<Predicate>();
					buildWherePredicate(t, b, root, fields, predicates);
					Predicate[] predicateTemp = new Predicate[predicates.size()];
					predicates.toArray(predicateTemp);
					queryq.where(predicateTemp);
					queryq.orderBy(b.asc(root.get("sourceType")),b.desc(root.get("disOrder")));
				}
			});
		} finally {
			logger.debug("list end");
		}
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.commons.service.IBaseService#add(cn.desk.commons.entity.BaseEntity
	 * )
	 */
	@Override
	public void add(T t) {
		logger.debug("add start");
		if(t.getId()!=null){
			T temp = baseDao.load(t.getClass(), t.getId());
			if (temp != null) {
				throw new DeskException("EM0001", t);
			}
		}
		List<T> list=baseDao.list(t.getClass(),new EqualQueryConditionBuilder<T>("path", t.getPath()));
		if(list.size()>0){
			throw new DeskException("EMLK0003", t,t.getPath());
		}
		baseDao.insert(t);
		logger.debug("add end");
	}
}
